<script setup>
import { computed, inject, ref, useSlots } from 'vue'
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import { JBoltApi } from '@/service/request'

dayjs.extend(customParseFormat)

const props = defineProps({
    field: {
        type: String
    },
    /**
     * 列最小宽度，把剩余宽度按比例分配
     */
    minWidth: {
        type: [Number, String]
    },
    width: {
        type: [Number, String]
    },
    editRender: {
        type: Object
    },
    /** 编辑选项 */
    editable: {
        type: String,
        validator: (value) => ['input', 'select', 'treeSelect', 'textarea', 'date'].includes(value)
    },
    /** 编辑组件要传入的Props */
    editComponentOption: {
        type: Object,
        default: () => ({})
    },
    /** 提交的url */
    editSubmitUrl: {
        type: String
    },
    /** 提交时的字段名，默认值同field属性值 */
    editSubmitField: {
        type: String
    },
    /** 提交的额外数据 */
    editSubmitData: {
        type: [Object, Array]
    },
    sortBy: {
        type: [Function, String, Array]
    }
})

const slots = useSlots()
const emits = defineEmits(['handleSubmit'])

const sortBy = computed(() => {
    return props.sortBy ?? sortHandler
})

/**
 * 阻止默认的排序
 */
function sortHandler() {
    return 0
}

const columnRef = ref()

/** 编辑相关  start */

/**
 * 当前正在编辑的列
 */
const exitEditState = inject('exitEditState')
const currentEditValue = inject('currentEditValue')
const currentEditingColumn = inject('currentEditingColumn')

const minWidth = computed(() => {
    return props.editable && currentEditingColumn?.value == props.field
        ? 200
        : props.minWidth
})

const width = computed(() => {
    return props.editable && currentEditingColumn?.value == props.field
        ? undefined
        : props.width
})

/**
 * 避免编辑日期时，双击其他单元格时，日期组件参数异常导致的报错
 */
const datePickerRef = ref(null)
const dateCurrentEditValue = computed(() => {
    if (
        datePickerRef.value &&
        currentEditValue?.value &&
        datePickerRef.value.valueFormat
    ) {
        const format = datePickerRef.value.valueFormat
        if (dayjs(currentEditValue?.value, format, false).isValid()) {
            return currentEditValue?.value
        } else {
            return undefined
        }
    }
    return undefined
})

const defaultEditRenderOptions = computed(() => {
    return {
        enabled: props.editable
    }
})

const editRender = computed(() => {
    return props.editable
        ? Object.assign({}, defaultEditRenderOptions.value, props.editRender)
        : undefined
})

const showDefaultEditSlot = computed(() => {
    return !slots['edit']
})

const editField = computed(() => {
    return props.editSubmitField ?? props.field
})

function editSubmit(row) {
    if (props.field && editField) {
        const submitData = {
            id: row.id,
            ...row,
            [editField.value]: currentEditValue?.value
        }
        Object.assign(submitData, props.editSubmitData)
        JBoltApi.post(props.editSubmitUrl, submitData).then((res) => {
            console.log('1111',res.result.data)
            emits('handleSubmit', row, res.result.data)
            row[props.field] = res.result.data[props.field]
            exitEditState?.()
        })
    }
}

/** 编辑相关  end */
</script>

<template>
    <vxe-column
        ref="columnRef"
        :sort-by="sortBy"
        :edit-render="editRender"
        :field="props.field"
        :min-width="minWidth"
        :width="width"
    >
        <template v-for="(_item, key) in slots" :key="key" #[key]="data">
            <slot :name="key" v-bind="data ?? {}" />
        </template>

        <template
            v-if="props.field && props.editable && showDefaultEditSlot"
            #edit="{ row }"
        >
            <div>
                <n-input
                    v-if="props.editable === 'input' || props.editable === 'textarea'"
                    v-model:value="currentEditValue"
                    :type="props.editable === 'input' ? 'text' : 'textarea'"
                    v-bind="props.editComponentOption"
                >
                    <template #suffix>
                        <jb-btn
                            icon="uis:check"
                            text
                            type="success"
                            tip-text="保存"
                            size="small"
                            @click="editSubmit(row)"
                        ></jb-btn>
                        <jb-btn
                            icon="mdi:remove"
                            text
                            type="error"
                            tip-text="取消"
                            size="small"
                            @click="exitEditState?.()"
                        ></jb-btn>
                    </template>
                </n-input>

                <div
                    v-if="props.editable === 'select'"
                    class="flex justify-between items-center"
                >
                    <jb-select
                        v-model:value="currentEditValue"
                        :clearable="false"
                        class="min-w-150px"
                        :to="false"
                        v-bind="props.editComponentOption"
                    ></jb-select>
                    <div class="flex items-center">
                        <jb-btn
                            icon="uis:check"
                            text
                            type="success"
                            tip-text="保存"
                            size="small"
                            @click="editSubmit(row)"
                        ></jb-btn>
                        <jb-btn
                            icon="mdi:remove"
                            text
                            type="error"
                            tip-text="取消"
                            size="small"
                            @click="exitEditState?.()"
                        ></jb-btn>
                    </div>
                </div>

                <div
                    v-if="props.editable === 'treeSelect'"
                    class="flex justify-between items-center"
                >
                    <jb-tree-select
                        v-model:value="currentEditValue"
                        class="min-w-170px"
                        checkable
                        cascade
                        v-bind="props.editComponentOption"
                        multiple
                        :to="false"
                    ></jb-tree-select>
                    <div class="mt-10px flex justify-between">
                        <jb-btn
                            icon="uis:check"
                            text
                            type="success"
                            tip-text="保存"
                            size="small"
                            @click="editSubmit(row)"
                        ></jb-btn>
                        <jb-btn
                            icon="mdi:remove"
                            text
                            type="error"
                            tip-text="取消"
                            size="small"
                            @click="exitEditState?.()"
                        ></jb-btn>
                    </div>
                </div>

                <div v-if="props.editable === 'date'" class="flex items-center">
                    <n-date-picker
                        ref="datePickerRef"
                        v-model:formatted-value="dateCurrentEditValue"
                        class="min-w-150px"
                        value-format="yyyy-MM-dd HH:mm:ss"
                        type="datetime"
                        v-bind="props.editComponentOption"
                        :to="false"
                    ></n-date-picker>
                    <div class="flex items-center">
                        <jb-btn
                            icon="uis:check"
                            text
                            type="success"
                            tip-text="保存"
                            size="small"
                            @click="editSubmit(row)"
                        ></jb-btn>
                        <jb-btn
                            icon="mdi:remove"
                            text
                            type="error"
                            tip-text="取消"
                            size="small"
                            @click="exitEditState?.()"
                        ></jb-btn>
                    </div>
                </div>
            </div>
        </template>
    </vxe-column>
</template>

<style scoped></style>
